package wendyeq.iweb.blog.service.impl;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import wendyeq.iweb.blog.dao.IArchiveDAO;
import wendyeq.iweb.blog.dao.IArticleDAO;
import wendyeq.iweb.blog.dao.ICategoryDAO;
import wendyeq.iweb.blog.dao.ITagsDAO;
import wendyeq.iweb.blog.pojo.Archive;
import wendyeq.iweb.blog.pojo.Article;
import wendyeq.iweb.blog.pojo.Category;
import wendyeq.iweb.blog.pojo.Tags;
import wendyeq.iweb.blog.service.IArticleService;

@Service("articleServiceImpl")
public class ArticleServiceImpl implements IArticleService{
	private static final Logger logger = Logger.getLogger(ArticleServiceImpl.class);

	@Resource(name="articleDAO")
	private IArticleDAO articleDAO;

	@Resource(name="categoryDAO")
	private ICategoryDAO categoryDAO;

	@Resource(name="tagsDAO")
	private ITagsDAO tagsDAO;

	@Resource(name="archiveDAO")
	private IArchiveDAO archiveDAO;

	@Override
	public boolean save(Article entity) {
		logger.info("aid="+entity.getContent());
		this.articleDAO.saveOrUpdate(entity);
		for(String t: entity.getTags()){
			Tags tag = this.tagsDAO.findByTag(t);
			tag.getArticles().add(entity.getId());
			this.tagsDAO.saveOrUpdate(tag);
		}
		String catName = entity.getCategory();
		Category category = this.categoryDAO.findByName(catName);
		if(category!=null){
			category.setCount(category.getCount()+1);
			this.categoryDAO.saveOrUpdate(category);
		}
		Date createdTime = entity.getCreatedTime();
		SimpleDateFormat sy=new SimpleDateFormat("yyyy");
		SimpleDateFormat sm=new SimpleDateFormat("MM");
		String year = sy.format(createdTime);
		String month = sm.format(createdTime);
		Archive arch = archiveDAO.findByYM(year, month);
		if(arch!=null){
			System.out.println("count="+arch.getCount());
			System.out.println("name="+arch.getName());
			arch.setCount(arch.getCount()+1);
		}else{
			arch = new Archive();
			arch.setName(year+"-"+month);
			arch.setYear(year);
			arch.setMonth(month);
			arch.setCount(1);
		}
		archiveDAO.saveOrUpdate(arch);
		return false;
	}

	@Override
	public boolean delete(String id) {
		Article article = this.articleDAO.findById(id);
		for(String t: article.getTags()){
			Tags tag = this.tagsDAO.findByTag(t);
			tag.getArticles().remove(id);
			this.tagsDAO.saveOrUpdate(tag);
		}
		String catName = article.getCategory();
		Category category = this.categoryDAO.findByName(catName);
		if(category!=null){
			category.setCount(category.getCount()+1);
			this.categoryDAO.saveOrUpdate(category);
		}
		Date createdTime = article.getCreatedTime();
		SimpleDateFormat sy=new SimpleDateFormat("yyyy");
		SimpleDateFormat sm=new SimpleDateFormat("MM");
		String year = sy.format(createdTime);
		String month = sm.format(createdTime);
		Archive arch = archiveDAO.findByYM(year, month);
		if(arch!=null){
			arch.setCount(arch.getCount()-1);
			archiveDAO.saveOrUpdate(arch);
		} 
		return this.articleDAO.delete(id);
	}

	@Override
	public boolean modify(Article a) {
		Article old = articleDAO.findById(a.getId());
		old.setTitle(a.getTitle());
		old.setAlias(a.getAlias());
		old.setContent(a.getContent());
		old.setCategory(a.getCategory());
		old.setIsComment(a.getIsComment());
		Set<String> oldTags = old.getTags();
		Set<String> aTags = a.getTags();
		Set<Tags> tagsSet = new HashSet<Tags>();
		logger.warn("tagsSet=" + tagsSet + "--");
		Set<String> addTags = new HashSet<String>();
		if (oldTags == null) {
			old.setTags(aTags);
			addTags = aTags;
		}else{
			for(String otag : oldTags){
				for(String tag : aTags){
					if(!otag.equalsIgnoreCase(tag)){
						old.getTags().remove(otag);
						Tags t = this.tagsDAO.findByTag(otag);
						t.getArticles().remove(old.getId());
						this.tagsDAO.saveOrUpdate(t);
						old.getTags().add(tag);
						addTags.add(tag);
					}
				}
			}
		}
		old.setChangedTime(new java.util.Date());
		for(String t : addTags){
			Tags tag =	this.tagsDAO.findByTag(t);
			this.tagsDAO.updateByArticle(tag.getId(), old.getId());
		}
		return this.articleDAO.saveOrUpdate(a);
	}
	@Override
	public Article findById(String id) {
		return this.articleDAO.findById(id);
	}

	@Override
	public List<Article> findByPage(int min, int max) {
		return this.articleDAO.findByPage(min, max);
	}

	@Override
	public List<Article> findAll() {
		return this.articleDAO.findAll();
	}

	@Override
	public Article findByAlias(String alias, String date){
		DateFormat format = new SimpleDateFormat("yyyy-MM-dd");    
		Date time= null;    
		try {    
			time = format.parse(date);  // Thu Jan 18 00:00:00 CST 2007    
		} catch (ParseException e) {    
			logger.error(e);    
		} 
		return this.articleDAO.findByAlias(alias,time);
	}

	@Override
	public List<Article> findByCat(int min, int max, String cat) {
		return this.articleDAO.findByCat(min,max,cat);
	}

	@Override
	public List<Article> findByTag(int min, int max, String tag) {
		List<Article> articles = new ArrayList<Article>(0);
		logger.warn(tag);
		Tags t = this.tagsDAO.findByTag(tag);
		logger.warn(t.getArticles().size());
		int size = t.getArticles().size();
		if (size < max)
			max = size;
		for(int i = min;i<max;i++){
			Object[] ik = t.getArticles().toArray();
			articles.add(this.findById(ik[i].toString()));
		}
		logger.warn("articles"+articles.size());
		return articles;
	}

	@Override
	public List<Article> findByArchive(int min ,int max ,String archive) {
		DateFormat format = new SimpleDateFormat("yyyy-MM");    
		Date date= null;    
		try {    
			date = format.parse(archive);  // Thu Jan 18 00:00:00 CST 2007    
		} catch (ParseException e) {    
			logger.error(e);    
		} 
		System.out.println("date = "+date);
		return this.articleDAO.findByArchive(min,max,date);
	}
	/***
	 * 通过序列化文件进行批量插入
	 * */
	@SuppressWarnings("unchecked")
	@Override
	public Collection<Article> saveOrUPdatebatch(String file) {
		FileInputStream fis=null;
		ObjectInputStream ois=null;
		List<Article> al=null;
		try{
			fis = new FileInputStream(file);
			ois = new ObjectInputStream(fis);
			al=(List<Article>)ois.readObject();
			return saveOrUPdatebatch(al);
		}catch(Exception e){
			logger.info("批量插入数据异常");
			logger.info(e.getMessage());
		}finally{
			if(fis!=null){
				try {
					fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					logger.info(file+"序列化文件读取异常");
					logger.info(e.getMessage());
				}
			}
			if(ois!=null){
				try {
					ois.close();
				} catch (IOException e) {
					logger.info(file+"序列化文件ObjectInputStream 异常");
					logger.info(e.getMessage());
				}
			}

		}
		// TODO Auto-generated method stub
		return null;
	}
	/***
	 * 批量插入文章
	 * */
	@Override
	public Collection<Article> saveOrUPdatebatch(List<Article> al) {
		// TODO Auto-generated method stub
		Collection<Article> ca=null;
		if(al==null||al.size()==0){
			return null;
		}else{
			ca=this.articleDAO.saveOrUPdatebatch(al);
			return ca;
		}
	}

	@Override
	public List<Article> findByDateCategory(String category, Date date) {
		// TODO Auto-generated method stub
		return this.articleDAO.findByDateCategory(category, date);
	}

	/*
	 public void insert(String title, String content, String catName,
			Boolean isComment) {
		Article article = new Article(title, content);
		//article.setCategory(catName);
		article.setIsComment(isComment);
		//String aid = this.articleDAO.saveOrUpdate(article);
		//this.categoryDAO.updateCountAdd(catName);
	}

	public void insert(String title, String content, String catName,
			Boolean isComment, String[] tags) {
		Set<Tags> tagsSet = new HashSet<Tags>();
		Set<String> tagList = new HashSet<String>();
		for (String t : tags) {
			Tags tag = this.tagsDAO.findByTag(t);
			tagsSet.add(tag);
			tagList.add(tag.getName());
		}
		Article article = new Article(title, content);
		//article.setCategory(catName);
		article.setIsComment(isComment);
		//article.setTags(tagList);
		//String aid = this.articleDAO.saveOrUpdate(article);
		//this.categoryDAO.updateCountAdd(catName);
		for (Iterator<Tags> i = tagsSet.iterator(); i.hasNext();) {
			//this.tagsDAO.updateByArticle(i.next().getId(), aid);
		}
	}

	public void update(String id, String title, Boolean isComment,String catName, String content) {
		logger.warn("do update tags is null");
		Article article = this.articleDAO.findById(id);
		logger.warn(article.getTitle());
		article.setTitle(title);
		article.setIsComment(isComment);
		//article.setCategory(catName);
		article.setContent(content);
		article.setChangedTime(new java.util.Date());	
		logger.warn(article.getTitle());
		this.articleDAO.saveOrUpdate(article);
	}

	public void update(String id, String title, Boolean isComment,String catName, String content, String[] tags) {
		logger.warn("do update tags not null" );
		Article article = this.articleDAO.findById(id);
		logger.warn(article.getTitle());
		article.setTitle(title);
		article.setIsComment(isComment);
		//article.setCategory(catName);
		article.setContent(content);
		//Set<String> oldTags = article.getTags();
		Set<Tags> tagsSet = new HashSet<Tags>();
		logger.warn("tagsSet=" + tagsSet + "--");
		Set<String> tagList = new HashSet<String>();
//		if (oldTags == null) {
//			for (String t : tags) {
//				tagList.add(t);
//			}
//			article.setTags(tagList);
//		}else{
//			for(String otag : oldTags){
//				for(String tag : tags){
//					if(!otag.equalsIgnoreCase(tag)){
//						article.getTags().remove(otag);
//						Tags t = this.tagsDAO.findByTag(otag);
//						t.getArticle().remove(id);
//						this.tagsDAO.saveOrUpdate(t);
//						article.getTags().add(tag);
//						tagList.add(tag);
//					}
//				}
//			}
//		}
		article.setChangedTime(new java.util.Date());
		this.articleDAO.saveOrUpdate(article);
		for(String t : tagList){
			Tags tag =	this.tagsDAO.findByTag(t);
//			this.tagsDAO.updateByArticle(tag.getId(), id);
		}
	}

	public void updateByVisitor(Article article, String visid) {
//		article.getVisitors().add(visid);
		this.articleDAO.saveOrUpdate(article);
	}

	//when update tag do this
	public void updateTags(String oldTag, String newTag){
		Tags t = this.tagsDAO.findByTag(oldTag);
//		Set<String> aids = t.getArticle();
//		for (String aid : aids){
//			Article a = this.articleDAO.findById(aid);
//			a.getTags().remove(oldTag);
//			a.getTags().add(newTag);
//			this.articleDAO.saveOrUpdate(a);
//		}
	}

	//when remove tag do this
	public void updateByTags(String aid, String tag) {
		Article a = this.articleDAO.findById(aid);
		a.getTags().remove(tag);
		this.articleDAO.saveOrUpdate(a);
	}

	public void updateCategory(String oldName, String newName) {
		List<Article> articles = this.articleDAO.findByCat(oldName);
		for(Article a : articles){
//			a.setCategory(newName);
			this.articleDAO.saveOrUpdate(a);
		}
	}

	public void updateByCategory(String catName) {
		if(this.categoryDAO.findByName("Default")==null){
			logger.warn("do new default");
			this.categoryDAO.saveOrUpdate(new Category("Default"));
		}
		List<Article> articles = this.articleDAO.findByCat(catName);
		for(Article a : articles){
//			a.setCategory("Default");
			this.articleDAO.saveOrUpdate(a);
//			this.categoryDAO.updateCountAdd("Default");
		}
	}

	public boolean delete(String id) {
		Article article = this.articleDAO.findById(id);
//		this.categoryDAO.updateCountDec(article.getCategory());
//		for(String t: article.getTags()){
//			Tags tag = this.tagsDAO.findByTag(t);
//			tag.getArticle().remove(id);
//			this.tagsDAO.saveOrUpdate(tag);
//		}
		this.articleDAO.delete(id);
		return false;
	}

	public List<Article> findAll() {
		return this.articleDAO.findAll();
	}

	public Article findById(String id) {
		return this.articleDAO.findById(id);
	}

	public List<Article> findByPage(int min, int max) {
		return this.articleDAO.findByPage(min, max);
	}

	public List<Article> findByCat(String cat) {
		return this.articleDAO.findByCat(cat);
	}

	public List<Article> findByTag(String tag) {
		List<Article> articles = new ArrayList<Article>(0);
		logger.warn(tag);
		Tags t = this.tagsDAO.findByTag(tag);
//		logger.warn(t.getArticle().size());
//		for (Iterator<String> i = t.getArticle().iterator(); i.hasNext();) {
//			articles.add(this.findById(i.next()));
//		}
		logger.warn("articles"+articles.size());
		return articles;
	}

	public List<Article> findByArchive(String archive) {
		DateFormat format = new SimpleDateFormat("yyyy-MM");    
        Date date= null;    
        try {    
            date = format.parse(archive);  // Thu Jan 18 00:00:00 CST 2007    
        } catch (ParseException e) {    
            logger.error(e);    
        } 
        System.out.println("date = "+date);
		return this.articleDAO.findByArchive(date);
	}

	public Article findByTitle(String title, String date) {
		DateFormat format = new SimpleDateFormat("yyyy-MM-dd");    
        Date time= null;    
        try {    
            time = format.parse(date);  // Thu Jan 18 00:00:00 CST 2007    
        } catch (ParseException e) {    
            logger.error(e);    
        } 

		return this.articleDAO.findByTitle(title,time);
	}
	 */
}